using System.Net.Sockets;
using System;
using Server.Tools;
using System.Text;
using System.Data;
using Server.Dao;

namespace Server.Net
{
	class ProcessDaoRequest
	{
        private byte packageIdentifier;

        private NetService netService;

        private SocketAsyncEventArgs args;

        private string returnCode;

        public ProcessDaoRequest(NetService netService)
        {
            this.netService = netService;
        }

		public void ProcessPackage(SocketAsyncEventArgs e)
		{
            try
            {
                args = e;
                byte[] b;
                int offset = 0;
                AsyncUserToken token = (AsyncUserToken)e.UserToken;
                if (token.State == AsyncUserToken.WaitNextSpillOverPackagePart)
                {
                    b = token.Buffer;
                }
                else
                {
                    b = e.Buffer;
                    offset = e.Offset + token.Offset;
                }

                packageIdentifier = b[offset + 4];
                string code = Encoding.ASCII.GetString(b, offset + 5, 4);
                returnCode = (Convert.ToInt32(code) + 1).ToString();
				object[] parameters = (object[])ByteArrayParser.ByteArrayToObject(b, offset + 9, token.PackageLength - 9);
                switch (code)
                {
					case "2000":
						new ProcedureService().PRo_BackUp(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2002":
						new ProcedureService().Pro_Restore(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2004":
						new ProcedureService().Pro_GetAllSubject(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2006":
						new ProcedureService().Pro_GetQuestionTypeBySubjectName(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2008":
						new ProcedureService().Pro_GetAllExamModel(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2010":
						new ProcedureService().Pro_GetExamModelByModelName(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2012":
						new ProcedureService().Pro_AddSubject(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2014":
						new ProcedureService().Pro_DelSubject(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2016":
						new ProcedureService().Pro_UpdateSubject(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2018":
						new ProcedureService().Pro_UpdateUser(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2020":
						new ProcedureService().Pro_GetQuestionTypeTotalNumByQuestionType(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2022":
						new ProcedureService().Pro_GetUserByName(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2024":
						new ProcedureService().Pro_AddUser(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2026":
						new ProcedureService().Pro_DelUser(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2028":
						new ProcedureService().Pro_GetQuestionsRequire(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2030":
						new ProcedureService().Pro_GetUser(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;
					case "2032":
						new ProcedureService().Pro_ChangePassword(parameters, token.UserLevel, new Delegate_AffectedRowsReach(AffectedRowsCallback));
						break;
					case "2034":
						new ProcedureService().Pro_GetUserLogin(parameters, token.UserLevel, new Delegate_DataTableReach(DataTableCallback));
						break;

                    default:
                        LogService.Instance.Log.Error("未知请求 " + "From[" + e.AcceptSocket.RemoteEndPoint + "] " + code + "---" + token.PackageLength);
                        break;
                }
            }
            catch (Exception ee)
            {
                LogService.Instance.Log.Error("处理Procedure数据包过程出错！" + ee.ToString());
            }
		}

        private void DataTableCallback(DataTable dt)
        {
            netService.SendAsync(args.AcceptSocket, packageIdentifier, returnCode, ByteArrayParser.ObjectToByteArray(dt));
        }

        private void AffectedRowsCallback(int affectedRows)
        {
            netService.SendAsync(args.AcceptSocket, packageIdentifier, returnCode, affectedRows.ToString());
        }
	}
}